package com.zhuoyue.biz.core.command.cmd.common.faa;

import com.alibaba.fastjson.JSONObject;
import com.zhuoyue.biz.core.command.cmd.common.faa.base.MultiFunctionSwitch0Faa8A09Utils;
import com.zhuoyue.common.constant.*;
import com.zhuoyue.biz.core.api.dao.DeviceDao;
import com.zhuoyue.biz.core.api.dao.ZigbeeDevicePropertyMapper;
import com.zhuoyue.biz.core.api.domain.DeviceAndGatewayDO;
import com.zhuoyue.biz.core.api.domain.DeviceDO;
import com.zhuoyue.biz.core.api.domain.ZigbeeDeviceProperty;
import com.zhuoyue.biz.core.api.dto.req.ControlReq;
import com.zhuoyue.biz.core.command.cmd.common.faa.base.BaseCmd;
import com.zhuoyue.biz.core.command.cmd.common.faa.base.IndexType_0FAA8A09;
import com.zhuoyue.common.utils.CmdUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author hewenze
 */
@Component
public class MultiFunctionSwitch0Faa8A09 extends BaseCmd {

    @Autowired
    private static DeviceDao deviceDao;
    @Autowired
    private static ZigbeeDevicePropertyMapper zigbeeDevicePropertyMapper;
    private static String enableValue = "0000";
    @Autowired
    private DeviceDao deviceDao1;
    @Autowired
    private ZigbeeDevicePropertyMapper zigbeeDevicePropertyMapper1;

    @Autowired
    private StringRedisTemplate redisTemplate1;
    @Autowired
    private static StringRedisTemplate redisTemplate;

    private static final String OPEN = "OPEN";
    private static final String CLOSE = "CLOSE";
    private static final String SET_MODE = "SETMODE";
    /**
     * od+deviceType+productType
     */
    private static final String OD_D_P_0FAA0D04 = "0FAA0D04";
    private static final String PAUSE = "PAUSE";
    private static final String OD_DEVICE_PRODUCT_TYPE = "odDeviceProductType";
    private static final String SYMBOL_ = "_";
    private static final String WAY_VALUE_0 = "0";
    private static final String DO_NOT_ENABLE = "00";
    private static final String ENABLE = "01";

    @PostConstruct
    public void init() {
        zigbeeDevicePropertyMapper = zigbeeDevicePropertyMapper1;
        deviceDao = deviceDao1;
        redisTemplate = redisTemplate1;
    }

    public static String control(DeviceAndGatewayDO deviceAndGatewayDO, ControlReq controlReq, String way) {
        String cmd = "";
        //基类中直接/延时控制开关模块
        cmd = BaseCmd.control(deviceAndGatewayDO, controlReq, way);

        //此设备特定功能模块
        switch (controlReq.getControlType()) {
            //配置继电器控制
            case ControlType.RELAY_REQUEST:
                cmd = getControlCmd(deviceAndGatewayDO, relayControl(deviceAndGatewayDO, controlReq));
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id", deviceAndGatewayDO.getId());
                jsonObject.put("deviceMac", deviceAndGatewayDO.getZigbeeMac());
                jsonObject.put("odIndex", deviceAndGatewayDO.getOdIndex());
                jsonObject.put("productType", deviceAndGatewayDO.getProductType());
                jsonObject.put("deviceType", deviceAndGatewayDO.getDeviceType());
                jsonObject.put("controlType", controlReq.getActions().get("state") == null ? "" : controlReq.getActions().get("state").toString());
                redisTemplate.opsForValue().set("zyzn_relayControl_gatewayMac_" + deviceAndGatewayDO.getGatewayMac(), String.valueOf(jsonObject), 5, TimeUnit.SECONDS);
                System.out.println("继电器控制" + cmd);
                break;
            //配置联动
            case ControlType.LINKAGE_REQUEST:
                cmd = getControlCmd(deviceAndGatewayDO, linkageSetCmd(controlReq));

                break;
            default:
                break;

        }
        return cmd;
    }

    /**
     * 配置继电器控制
     *
     * @param controlReq
     * @return
     */
    public static String relayControl(DeviceAndGatewayDO deviceAndGatewayDO, ControlReq controlReq) {
        //继电器使能开关数据
        String state = controlReq.getActions().get("state") != null ? controlReq.getActions().get("state").toString() : "";
        String[] s1 = StringUtils.split(deviceAndGatewayDO.getProductType(), "_");
        String way = s1[s1.length - 1];
        String way1Value = "1";
        String way2Value = "1";
        String way3Value = "1";
        String way4Value = "1";

        List<DeviceDO> deviceDos = deviceDao.selectDeviceIdByDeviceMac(deviceAndGatewayDO.getZigbeeMac());

        for (DeviceDO deviceDO : deviceDos) {
            String[] s = StringUtils.split(deviceDO.getProductType(), "_");
            if (s.length == 1) {
                continue;
            }
            String wayNumber = s[s.length - 1];
            ZigbeeDeviceProperty zigbeeDeviceProperty = zigbeeDevicePropertyMapper.selectById(deviceDO.getId());

            if (zigbeeDeviceProperty != null) {
                String property = zigbeeDeviceProperty.getProperty();
                JSONObject jsonObject = JSONObject.parseObject(property);
                String state1 = jsonObject.get("relay") != null ? jsonObject.get("relay").toString() : "1";
                switch (wayNumber) {
                    case "1":
                        way1Value = change(state1);
                        replaceFun(way1Value, state1, wayNumber);
                        break;
                    case "2":
                        way2Value = change(state1);
                        replaceFun(way2Value, state1, wayNumber);
                        break;
                    case "3":
                        way3Value = change(state1);
                        replaceFun(way3Value, state1, wayNumber);
                        break;
                    case "4":
                        way4Value = change(state1);
                        replaceFun(way4Value, state1, wayNumber);
                        break;
                    default:
                        break;
                }
            }


        }

        switch (way) {
            case "1":
                way1Value = change(state);
                replaceFun(way1Value, state, way);
                break;
            case "2":
                way2Value = change(state);
                replaceFun(way2Value, state, way);
                break;
            case "3":
                way3Value = change(state);
                replaceFun(way3Value, state, way);
                break;
            case "4":
                way4Value = change(state);
                replaceFun(way4Value, state, way);
                break;
            default:
                break;
        }


        //二进制
        String binary = way4Value + way3Value + way2Value + way1Value;

        String[] str = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
        int integer = Integer.valueOf(binary, 2);

        if (StringUtils.startsWithIgnoreCase(state, OPEN)) {
            String reverse = StringUtils.reverse(enableValue);
            int enableValue16 = Integer.valueOf(reverse, 2);
            return IndexType_0FAA8A09.getEnumType("control") + "15" + "02" + "F" + str[integer] + "F" + str[enableValue16];
        }

        if (StringUtils.startsWithIgnoreCase(state, CLOSE)) {
            if (StringUtils.indexOf(state, SYMBOL_) == -1) {
                return IndexType_0FAA8A09.getEnumType("control") + "15" + "02" + "F" + str[integer] + "01";
            }
            String reverse = StringUtils.reverse(enableValue);
            int enableValue16 = Integer.valueOf(reverse, 2);
            return IndexType_0FAA8A09.getEnumType("control") + "15" + "02" + "F" + str[integer] + "F" + str[enableValue16];
        }
        return "";

    }

    public static String change(String state) {
        String stateValue = "1";
        if (StringUtils.startsWithIgnoreCase(state, OPEN)) {
            stateValue = "1";
        }
        if (StringUtils.startsWithIgnoreCase(state, CLOSE)) {
            stateValue = "0";
        }
        return stateValue;
    }

    public static void replaceFun(String way1Value, String state, String way) {
        StringBuilder stringBuilder = new StringBuilder(enableValue);
        if (StringUtils.equals(WAY_VALUE_0, way1Value)) {
            Boolean aBoolean = changeRelayEnable(state);
            if (aBoolean) {
                enableValue = stringBuilder.replace(Integer.parseInt(way) - 1, Integer.parseInt(way), "1").toString();
            } else {
                enableValue = stringBuilder.replace(Integer.parseInt(way) - 1, Integer.parseInt(way), "0").toString();
            }
        } else {
            enableValue = stringBuilder.replace(Integer.parseInt(way) - 1, Integer.parseInt(way), "0").toString();
        }
    }

    public static Boolean changeRelayEnable(String state) {
        if (StringUtils.indexOf(state, SYMBOL_) == -1) {
            return true;
        }

        if (StringUtils.startsWithIgnoreCase(state, CLOSE)) {
            String[] isEnable = StringUtils.split(state, "_");
            //关闭使能
            if (StringUtils.equals(isEnable[1], DO_NOT_ENABLE)) {
                return false;
            }
            //打开使能
            if (StringUtils.equals(isEnable[1], ENABLE)) {
                return true;
            }
        }
        return false;
    }


    public static String linkageSetCmd(ControlReq controlReq) {
        Map<String, Object> actions = controlReq.getActions();

        String endDeviceMac = actions.get("endDeviceMac") != null ? actions.get("endDeviceMac").toString() : "";
        String way = actions.get("way") != null ? actions.get("way").toString() : "";
        //目标设备路数，单色温、双色温等默认为"01"
        String targetWay = "01";
        String mode = actions.get("mode") != null ? actions.get("mode").toString() : "";
        String deviceType = actions.get("deviceType") != null ? actions.get("deviceType").toString() : "";
        String startSwitchState = actions.get("startSwitchState") != null ? actions.get("startSwitchState").toString() : "";
        Integer modeIndex = actions.get("modeIndex") != null ? Integer.parseInt(actions.get("modeIndex").toString()) : null;
        String endState = "";
        String childIndex = "";
        //设备源状态+参数1~5
        String params = "";
        //同步、切换标识
        String modeCmd = "";
        switch (deviceType) {
            //静音窗帘
            case "curtain":
                LinkageCurtainActionsJson linkageCurtainActionsJson = actions.get("linkageCurtainActionsJson") != null ? (LinkageCurtainActionsJson) actions.get("linkageCurtainActionsJson") : null;
                System.out.println("窗帘" + linkageCurtainActionsJson);
                int percentage = 100;
                if (linkageCurtainActionsJson != null && linkageCurtainActionsJson.getPercentage() != null) {
                    percentage = linkageCurtainActionsJson.getPercentage();
                }
                endState = "";
                if (linkageCurtainActionsJson != null && linkageCurtainActionsJson.getState() != null) {
                    endState = linkageCurtainActionsJson.getState();
                }

                switch (mode) {
                    case "delete":
                        modeCmd = "FFFF";
                        params = "FF" + "FF" + "FF" + "FFFFFF";
                        break;
                    case "sync":
                        modeCmd = "01FF";
                        params = "FF" + "FF" + "FF" + "FFFFFF";
                        break;
                    case "switch":
                        modeCmd = "FF01";
                        params = "FF" + "FF" + "FF" + "FFFFFF";
                        break;
                    case "customize":
                        modeCmd = "FFFF";
                        String stateCmd = "";
                        String baseState = "";
                        if (OPEN.equals(startSwitchState)) {
                            baseState = "01";
                        } else if (CLOSE.equals(startSwitchState)) {
                            baseState = "02";
                        }
                        if (OPEN.equals(endState)) {
                            stateCmd = "01";
                            params = baseState + stateCmd + CmdUtils.intToHexTwo(percentage) + "00" + "FF" + "FF";
                        } else if (CLOSE.equals(endState)) {
                            stateCmd = "02";
                            params = baseState + stateCmd + "02" + "00" + "FF" + "FF";
                        } else if (PAUSE.equals(endState)) {
                            stateCmd = "02";
                            params = baseState + stateCmd + "04" + "00" + "FF" + "FF";
                        }
                        System.out.println("自定义参数数据帧" + params);
                        System.out.println("五个参数" + params);
                        break;
                    default:
                        break;

                }
                break;
            //灯光类（单色温、双色温、开关控制盒）
            case "light":
                LinkageLightActionsJson linkageLightActionsJson = actions.get("linkageLightActionsJson") != null ? (LinkageLightActionsJson) actions.get("linkageLightActionsJson") : null;
                int duration = linkageLightActionsJson.getDuration() != null ? linkageLightActionsJson.getDuration() : 0;
                int setBrightness = linkageLightActionsJson.getSetBrightness() != null ? linkageLightActionsJson.getSetBrightness() : 0;
                int setColorTemperature = linkageLightActionsJson.getSetColorTemperature() != null ? linkageLightActionsJson.getSetColorTemperature() : 0;
                // String state1 = linkageLightActionsJson.getState() != null ? linkageLightActionsJson.getState() : "";

                endState = linkageLightActionsJson.getState();
                switch (mode) {
                    case "delete":
                        modeCmd = "FFFF";
                        params = "FF" + "FF" + "FF" + "FFFFFF";
                        break;
                    case "sync":
                        modeCmd = "01FF";
                        params = "FF" + "00" + "00" + "FFFFFF";
                        break;
                    case "switch":
                        modeCmd = "FF01";
                        params = "FF" + "00" + "00" + "FFFFFF";
                        break;
                    case "customize":
                        modeCmd = "FFFF";
                        String stateCmd = "";
                        String baseState = "";
                        if (OPEN.equals(startSwitchState)) {
                            baseState = "01";
                        } else if (CLOSE.equals(startSwitchState)) {
                            baseState = "02";
                        }

                        if (OPEN.equals(endState)) {
                            if (actions.containsKey(OD_DEVICE_PRODUCT_TYPE)) {
                                String type = actions.get(OD_DEVICE_PRODUCT_TYPE).toString();
                                //若是开关控制盒,打开为控制命令为01，直接打开；03为调整色温+亮度
                                if (OD_D_P_0FAA0D04.equals(type)) {
                                    stateCmd = "01";
                                } else {
                                    stateCmd = "03";
                                }
                            } else {
                                stateCmd = "03";
                            }

                            params = baseState + stateCmd + CmdUtils.intToHexTwo(duration) + "00" + CmdUtils.intToHexTwo(setBrightness) + CmdUtils.intToHexTwo(setColorTemperature);
                        } else if (CLOSE.equals(endState)) {
                            stateCmd = "02";
                            params = baseState + stateCmd + CmdUtils.intToHexTwo(duration) + "00" + "FF" + "FF";
                        } else if (SET_MODE.equals(endState)) {
                            //设置模式
                            if (modeIndex.equals(-1)) {
                                stateCmd = "0F";
                                params = baseState + stateCmd + "FF" + "00" + "FF" + "FF";
                            } else {
                                stateCmd = "0E";
                                params = baseState + stateCmd + modeIndex + duration + "00" + "FF" + "FF";
                            }
                        }
                        System.out.println("自定义参数数据帧" + params);
                        System.out.println("五个参数" + params);
                        break;
                    default:
                        break;
                }
                break;
            //rgbw（灯带控制器控制盒）
            case "rgbw":
                LinkageRgbwActionsJson linkageRgbwActionsJson = (LinkageRgbwActionsJson) actions.get("linkageRgbwActionsJson");
                //灯带控制类型，开、关、调光、调色、模式
                String targetControlState = linkageRgbwActionsJson.getState();
                //联动控制模式，同步、交换、自定义
                switch (mode) {
                    case "delete":
                        modeCmd = "FFFF";
                        params = "FF" + "FF" + "FF" + "FFFFFF";
                        break;
                    case "sync":
                        modeCmd = "01FF";
                        params = "FF" + "00" + "00" + "FFFFFF";
                        break;
                    case "switch":
                        modeCmd = "FF01";
                        params = "FF" + "00" + "00" + "FFFFFF";
                        break;
                    case "customize":
                        modeCmd = "FFFF";

                        //源设置触发状态，开、关
                        String sourceState = "";
                        if (OPEN.equals(startSwitchState)) {
                            sourceState = "01";
                        } else {
                            sourceState = "02";
                        }

                        //控制对象路数，第一路：01=调光/调色，第二路：02=模式（七彩渐变、呼吸灯等）
                        if (SET_MODE.equals(targetControlState)) {
                            targetWay = "02";
                        } else {
                            targetWay = "01";
                        }

                        //参数1,灯光控制模式；02=调光；03=调色; 模式，（渐变：09，跳变：10，呼吸：11）
                        String parameter1 = "01";
                        String targetModeState = "";

                        int white = linkageRgbwActionsJson.getWhite() == null ? 0 : linkageRgbwActionsJson.getWhite();
                        int red = linkageRgbwActionsJson.getRed() == null ? 0 : linkageRgbwActionsJson.getRed();
                        int green = linkageRgbwActionsJson.getGreen() == null ? 0 : linkageRgbwActionsJson.getGreen();
                        int blue = linkageRgbwActionsJson.getBlue() == null ? 0 : linkageRgbwActionsJson.getBlue();
                        //若是调色或呼吸灯模式，则参数三为red, 否则为white

                        duration = linkageRgbwActionsJson.getDuration() == null ? 0 : linkageRgbwActionsJson.getDuration();
                        String parameter2 = CmdUtils.intToHexTwo(duration);
                        String parameter3 = "00";
                        String parameter4 = CmdUtils.intToHexTwo(green);
                        String parameter5 = CmdUtils.intToHexTwo(blue);

                        switch (targetControlState) {
                            case "AdjustBrightness":
                                parameter1 = "02";
                                parameter3 = CmdUtils.intToHexTwo(white);
                                break;
                            case "AdjustColor":
                                parameter1 = "03";
                                parameter3 = CmdUtils.intToHexTwo(red);
                                break;
                            case "TurnOffRequest":
                                parameter1 = "02";
                                parameter3 = parameter4 = parameter5 = "00";
                                break;
                            case "SETMODE":
                                targetModeState = linkageRgbwActionsJson.getModeState();
                                parameter2 = "00";
                                switch (targetModeState) {
                                    case ColorfulBulbLampMode.COLORFUL_GRADIENT:
                                        parameter1 = "09";
                                        break;
                                    case ColorfulBulbLampMode.COLORFUL_JUMP:
                                        parameter1 = "0A";
                                        break;
                                    case ColorfulBulbLampMode.BREATHING_LAMP:
                                        parameter1 = "0B";
                                        parameter3 = "F0";
                                        parameter4 = parameter5 = "00";
                                        break;
                                    default:
                                        break;
                                }
                                break;
                            default:
                                break;
                        }

                        duration = linkageRgbwActionsJson.getDuration() == null ? 0 : linkageRgbwActionsJson.getDuration();
                        params = sourceState + parameter1 + parameter2 + parameter3 + parameter4 + parameter5;
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        childIndex = MultiFunctionSwitch0Faa8A09Utils.index(startSwitchState, mode, way);
        String del = "delete";
        String paramCmd = "";
        if (StringUtils.equalsIgnoreCase(del, mode)) {
            paramCmd = "FF" + "FF" + "FFFFFFFFFFFFFFFF" + "FFFF" + modeCmd + params;
        } else {
            paramCmd = "0" + way + targetWay + endDeviceMac + "0000" + modeCmd + params;
        }

        return IndexType_0FAA8A09.getEnumType("linkage") + childIndex + CmdUtils.getDateLength(paramCmd) + paramCmd;
    }


    /**
     * 拼接数据帧
     *
     * @param deviceAndGatewayDO
     * @param cmd10To12
     * @return
     */
    public static String getControlCmd(DeviceAndGatewayDO deviceAndGatewayDO, String cmd10To12) {


        String cmd3To12 = DataBase.WRITE +
                DataBase.ONE +
                deviceAndGatewayDO.getGatewayMac() +
                deviceAndGatewayDO.getZigbeeMac() +
                cmd10To12;

        String cmd2 = CmdUtils.getDateLength(cmd3To12);

        String cmd13 = CmdUtils.getCmdBodySum(cmd3To12);

        String fullCmd = DataBase.DATA_HEAD +
                cmd2 +
                cmd3To12 +
                cmd13 +
                DataBase.DATA_END;

        return fullCmd;
    }
}
